package src.stateMachine;

import java.awt.Color;
import java.awt.Graphics;
import java.awt.Image;
import java.awt.image.BufferedImage;

import src.GameApplet;
import src.Ks;
import src.Level;
import src.Mouse;
import src.token.Token;

public class StateGame extends State {

	public static Token token_selected = null;

	public static Integer key = null;
	
	public static StateGame instance = null;
	
	
	public static long currentTime = 0;
	public static long initialTime = 0;
	
	public static boolean gameOver = false;
	
	
	public StateGame(){
		super();
		key = super.key;
	
	}
	
	/*public static int chain_w = 0;
	public static int chain_h = 0;*/
	
	//TODO: hacer que se pinte toda la cadena de clusters
	public static void paintChainSelected(){
		
		Token t;
		Color colorLevel = null;
		Color borderColor = new Color(0xffffff);
		
		
		
		
		//Pintando el token cuando el mouse esta presionado y se esta arrastrando:
		if (Mouse.mousePressed && token_selected != null){
				
			colorLevel =new Color(0x338333 * token_selected.level);
			g.setColor( colorLevel );
			g.fillRect(Mouse.pos_x, Mouse.pos_y, Ks.token_size, Ks.token_size);
			g.setColor(borderColor);
			g.draw3DRect(Mouse.pos_x, Mouse.pos_y, Ks.token_size, Ks.token_size, true);
			
			if (token_selected. m_next != null){
				paintTokenChainRight(token_selected,  Mouse.pos_x + Ks.token_size, colorLevel);
			}
			
			if (token_selected. m_prev != null){
				paintTokenChainLeft(token_selected,  Mouse.pos_x - Ks.token_size, colorLevel);
			}
			
			return;
			
			
		}
		

		
		

	}
	
	
	public static void paintTokenChainRight(Token t,int x,Color c){
		
		Token t2 = t.m_next;
		
		g.setColor(c);		
		g.fillRect(x , Mouse.pos_y, Ks.token_size, Ks.token_size);
		g.setColor(new Color(0xffffff));
		g.draw3DRect(x, Mouse.pos_y, Ks.token_size, Ks.token_size, true);
		
		
		if (t2.m_next != null){
			paintTokenChainRight(t.m_next,x + Ks.token_size, c);
		}

	}
	
	public static void paintTokenChainLeft(Token t,int x,Color c){
		
		Token t2 = t.m_prev;
		
		g.setColor(c);		
		g.fillRect(x , Mouse.pos_y, Ks.token_size, Ks.token_size);
		g.setColor(new Color(0xffffff));
		g.draw3DRect(x, Mouse.pos_y, Ks.token_size, Ks.token_size, true);
		
		
		if (t2.m_prev != null){
			paintTokenChainLeft(t.m_prev,x - Ks.token_size, c);
		}

	}

	
	public void update(){
		
		//Todavia no esta probado si funciona bien, en la teoria si :P
		Level.UpdateChains();
		updateChainSelected();
		updateTimeBar();
		
		StateMachine.setNextState(StateUpdateInput.key);
	}
	
	public static boolean levelLoaded = false;
	
	public void init(){
	
		if (!levelLoaded){
			Level.init();
			gameOver = false;
			
			
			initialTime = System.currentTimeMillis();
			//System.out.println("initialTime: "  + initialTime);
			
			levelLoaded = true;
			
			
		}
		
		if (b_buffer == null){
			b_buffer = new BufferedImage(Ks.SCREEN_WIDTH, Ks.SCREEN_HEIGHT, BufferedImage.TYPE_INT_ARGB);
		}
	}
	
	public void paint(){
		g = b_buffer.getGraphics();
		
		paintLevel();
		paintInterface();
		paintChainSelected();
		
		paintToScreen();
	}
	
	public static BufferedImage b_buffer = null;
	public static Graphics g = null;
	
	public static void paintLevel(){
		
		
		
		g.setColor(Ks.BgColor);
		g.fillRect(0,0,Ks.SCREEN_WIDTH, Ks.SCREEN_HEIGHT);
		
		
		for (int i = 0; i < Ks.columnas; i++){
			for (int j = 0; j < Ks.filas; j++){
			
			
				
				Token t = Level.levelData[i][j];
				
				if(t != null){
					g.setColor(new Color(0x338333 * Level.levelData[i][j].level) );
					g.fillRect(t.pos_x, t.pos_y, Ks.token_size, Ks.token_size);
					g.setColor(new Color(0xffffff));
					g.draw3DRect(t.pos_x, t.pos_y, Ks.token_size, Ks.token_size, true);
					
					
					
					g.setColor(new Color(0xff0000));
					
					if(t.m_prev != null){
						if (t.m_prev.level == t.level){
							g.draw3DRect(t.m_prev.pos_x, t.m_prev.pos_y, Ks.token_size, Ks.token_size, true);
							g.draw3DRect(t.pos_x, t.pos_y, Ks.token_size, Ks.token_size, true);
						}
					}
					
					if(t.m_next != null){
						if (t.m_next.level == t.level){
							g.draw3DRect(t.m_next.pos_x, t.m_next.pos_y, Ks.token_size, Ks.token_size, true);
							g.draw3DRect(t.pos_x, t.pos_y, Ks.token_size, Ks.token_size, true);
						}
					}
				}
				

				

			}
		}
			
		
	}
	
	
	
	public static void paintInterface(){
	
		
		g.setColor(Ks.BgInterface);
		g.fill3DRect(Ks.interface_posX, Ks.interface_posY, Ks.SCREEN_WIDTH, Ks.interface_height, true);
		
		g.setColor(Ks.borderInterface);
		g.draw3DRect(Ks.interface_posX, Ks.interface_posY, Ks.SCREEN_WIDTH, Ks.interface_height, false);
		
		paintTimeBar(); 
	}
	
	static int dc = 0x010101;
	public static void paintTimeBar(){
		g.setColor(Ks.BgColor);
		g.fillRect(5, Ks.interface_posY + 5,Ks.SCREEN_WIDTH - 5, 3  );
		
		g.setColor(new Color(0xffffff + dc));
		
		if (GameApplet.s_globalTick % 5 == 0){
			dc = dc + 0x010101;
		}
		
		long temp =(int)((Ks.totalTime - currentTime ) * (Ks.SCREEN_WIDTH - 5)) / Ks.totalTime;
		
		int toInt =(int) temp >> 32; //almaceno el float en un int manualmente.

		g.fillRect( 5, Ks.interface_posY + 5,toInt, 3  );
	}

	public static void updateTimeBar(){
		currentTime = System.currentTimeMillis() - initialTime;
		
	}
	
	public static void paintToScreen(){
		GameApplet.s_g.drawImage(b_buffer,0,0,GameApplet.s_instance);
	}
	
	public static void updateChainSelected(){
		
		if (Mouse.mousePressed){
			if (token_selected == null){
				token_selected = Level.getToken(Mouse.pos_x, Mouse.pos_y);
				
				
			}
			
		}
		else{
			if (token_selected != null){
				Level.changeTokenPosition(token_selected, Mouse.pos_x, Mouse.pos_y);
				
				Level.UpdateChains();
			}
			
			
			token_selected = null;
			
		}

	
	
	
	
	}
}
